﻿import caurina.transitions.Tweener;

class Secuenciador {
	var esc:Number = 1;
	var FAC_REP:Number = 1;   // factor de escala en reposo (escala constante)
	var FAC_IN_CON:Number = 9/8;  // factor de escala constante en zoom in
	var FAC_OUT_CON:Number = 8/9;   // factor de escala constante en zoom out
	var delta:Number = (FAC_IN_CON - FAC_REP) / 32;
	var fac:Number = FAC_REP;
	var z_in:Boolean;   // zoom in / zoom out
	var acel:Function;
	var desacel:Function;
	var _panel_zoom:PanelZoom;

	
	function Secuenciador(panel_zoom) {
		_panel_zoom = panel_zoom;
		trace(_panel_zoom);
	}

	function acel_in():Number {
		// Criterio de elección de una u otra alternativa: estética
	
		// Resultado: movimiento uniforme (más estético)
		//return FAC_IN_CON;
		
		// Resultado: movimiento acelerado
		return Math.min(FAC_IN_CON, fac+delta);
	}

	function desacel_in():Number {
		return Math.max(FAC_REP, fac-delta);
	}

	function acel_out():Number {
		// Criterio de elección de una u otra alternativa: estética
	
		// Resultado: movimiento uniforme (más estético)
		//return FAC_OUT_CON;
		
		// Resultado: movimiento acelerado
		return Math.max(FAC_OUT_CON, fac-delta);
	}

	function desacel_out():Number {
		return Math.min(FAC_REP, fac+delta);
	}

	var iid;
	var b_mov;
	var b_fin_mov;
	function ini_mov() {
		trace("ini_mov");
		//puede estar en un desplazamiento / scrolling
		/* finalización del estado de scrolling */

		if(z_in) {
			acel = acel_in;
			desacel = desacel_in;
		}
		else {
			acel = acel_out;
			desacel = desacel_out;
		}
		b_mov = true;
		b_fin_mov = false;
		mov();
	}

	function fin_mov() {
		b_mov=false;
	}

	function mov() {
		trace("mov " + b_mov + " " + " " + b_fin_mov + " " + esc);
		/* Significado de las variables:
		 * b_mov: el usuario mantiene presionado el manejador del scroll
		 * b_fin_mov: el movimiento del contenido scrolleado alcanzó la posición asociada al manejador
		 * caso:
		 * 1. El usuario arrastra el manejador del scroll
		 * 2. Luego de arrastrarlo lo mantiene presionado sin moverlo
		 * 3. El desplazamiento llega a la posición indicada por el manejador
		 * 4. El usuario mantiene presionado el manejador sin arrastrar
		 */
		if(!b_mov && b_fin_mov && iid!=undefined) {
			clearInterval(iid);
			iid = undefined;
		}
		if(b_mov && !b_fin_mov && iid==undefined) {
			iid = setInterval(this, "mov", 25);
		}

		if(b_mov) {
			fac = acel();   //aceleración con tope
		}
		else {
			fac = desacel();  // desaceleración con tope
		}
		
		if(fac!=FAC_REP) {   // condición de fin
			b_fin_mov = false;
			esc *= fac;
			// detección de tope alcanzado
			if(esc<1 || esc>3) {
				b_fin_mov = true;
				/* el factor fac (que es el facto de cambio de velocidad del zoom,
				 * es decir, la aceleración del movimiento del zoom), cuando arrastra valor de la operación
				 * contraria produce un efecto de cambio de sentido suave (de aumento a disminución o vice versa)
				 * por eso no se inicializa en 1 en la operación de ini_mov, si no sería duro el cambio de sentido
				 * cuando choca con un tope máximo o mínimo, al darse por finalizado el movimiento (b_fin_mov=true en la línea anterior)
				 * el factor fac no tiene oportunidad de volver a su estado en reposo, y dado el hecho de tope alcanzado
				 * tampoco es requerido producir ningún efecto suave, por eso se lo reinicia a su estado en reposo
				 */
				fac = FAC_REP;
				esc = Math.max(esc, 1);
				esc = Math.min(esc, 3);
				/* simulación de que el usuario soltó el botón de zoom
				 * por el caso especial del botón pan, que no tiene evento de onRelease,
				 * el cual en un botón de aumento o disminución del zoom invoca a fin_mov
				 * para que se deje de procesar la variable fac y se borre el intervalo de
				 * invocación a esta función (ver usos de b_mov más arriba)
				 */
				 b_mov = false;
			}
			_panel_zoom.zoom(esc);
		}
		else {
			b_fin_mov = true;
		}
	}

	var k_tiempo:Number = 0.2;   // k_tiempo = constante de tiempo por unidad de escala transfotmada, t / (esc - 1)
	var k_count:Number = 20;  // constante de cantidad de invocaciones por segundo transcurrido, k_count = c / t
	var esc_dif:Number;
	var co:Number;
	function pan() {
		esc_dif = esc-1;
		var t:Number = esc_dif * k_tiempo; // Math.max(0.5, Math.min(esc_dif * k_tiempo, 2));
		co = Math.round(t * k_count);
		trace(esc_dif + " " + co);
		Tweener.addCaller(this, {delay: 0, time: t, transition: "linear", count: co, onUpdate: this.pan_aux/*, onComplete: this.pan_aux_2*/});
	}
	
	function pan_aux() {
		esc -= esc_dif/co;
		_panel_zoom.zoom(esc);
	}
	
	function pan_aux_2() {
		esc = 1;
		_panel_zoom.zoom(esc);
	}
	
}